#pragma once

#include "IXImageDraw.h"
#include "Logic/Include/XBaseObjImpl.h"

#include <map>

enum
{
    ImageFlag_NotDelete = 0x1,
    ImageFlag_Icon      = 0x2,
    ImageFlag_Image     = 0x4,
    ImageFlag_BigIcon   = 0x8,
    ImageFlag_Colorize  = 0x10,
};

class CXImageDrawImpl : public CXBaseObjImpl<IXImageDraw>
{
    typedef CXBaseObjImpl<IXImageDraw> superclass;

    BEGIN_DEF_SKIN_CLASS(CXImageDrawImpl, superclass, gs_strGuidXSkin)
        IMP_BASIC_INTF(IXImageDraw, 0)
        IMP_BASIC_INTF(IXDraw, eIntf_NoCreate)
    END_DEF_SKIN_CLASS();
public:
    CXImageDrawImpl();
    virtual ~CXImageDrawImpl();

public:
    // IXImageDraw
    virtual HRESULT STDMETHODCALLTYPE   put_ImagePath(IN LPCTSTR szXNC);
    virtual HRESULT STDMETHODCALLTYPE   put_Icon(IN LPCTSTR szXNC, BOOL bBig);
    virtual HRESULT STDMETHODCALLTYPE   put_Icon(IN XICON xIcon, IN BOOL bDestroy);

    virtual HRESULT STDMETHODCALLTYPE   get_ImagePath(OUT BSTR* pszXNC);

    virtual HRESULT STDMETHODCALLTYPE   put_Image(IN XIMAGE xImage);

    virtual void    STDMETHODCALLTYPE   put_DrawType(IN ImageDrawType type);

    virtual HRESULT STDMETHODCALLTYPE   put_DrawParams(IN ImageDrawParams* pParam);
    virtual HRESULT STDMETHODCALLTYPE   get_DrawParams(OUT ImageDrawParams* pParam);

    virtual HRESULT STDMETHODCALLTYPE   get_ImageSize(OUT LPSIZE lpSize);

    virtual HRESULT STDMETHODCALLTYPE   put_Index(IN INT nHIndex, IN INT nVIndex);
    virtual HRESULT STDMETHODCALLTYPE   get_Index(IN LPINT pnHIndex, IN LPINT pnVIndex);

    virtual HRESULT STDMETHODCALLTYPE   put_SubCount(IN INT nHCount, IN INT nVCount);
    virtual HRESULT STDMETHODCALLTYPE   get_SubCount(IN LPINT pnHCount, IN LPINT pnVCount);

    virtual BOOL    STDMETHODCALLTYPE   IsDrawValid();

    virtual HRESULT STDMETHODCALLTYPE   put_AlphaMode(IN eImageAlphaMode nAlphaMode);
    virtual HRESULT STDMETHODCALLTYPE   get_AlphaMode(OUT eImageAlphaMode* pnAlphaMode);

    virtual HRESULT STDMETHODCALLTYPE   put_AlphaValue(IN BYTE byAlphaValue);
    virtual HRESULT STDMETHODCALLTYPE   get_AlphaValue(OUT LPBYTE pbyAlphaValue);

    virtual HRESULT STDMETHODCALLTYPE   put_TransparentColor(IN COLORREF clrTrans);
    virtual HRESULT STDMETHODCALLTYPE   get_TransparentColor(OUT LPCOLORREF pclrTrans);

    // IXDraw
    virtual HRESULT STDMETHODCALLTYPE   Draw(IN XCANVAS xCanvas, const RECT* lpDes);
    virtual HRESULT STDMETHODCALLTYPE   Draw(IN XCANVAS xCanvas, IN const RECT* lpSrc, IN const RECT* lpDes);

    virtual HANDLE  STDMETHODCALLTYPE   GetDrawBuffer(IN SIZE* pSize);
    virtual void    STDMETHODCALLTYPE   ReleaseDrawBuffer(IN HANDLE hBuffer);
    virtual HRESULT STDMETHODCALLTYPE   DrawBuffer(IN XCANVAS xCanvas, IN HANDLE hBuffer, IN const RECT* lpDes);

    virtual void    STDMETHODCALLTYPE   EnableColorize(IN BOOL bEnable);
    virtual void    STDMETHODCALLTYPE   Colorize(IN int hue, IN int sat, IN int light);

    // IBaseObj
    virtual void    STDMETHODCALLTYPE   OnFinalRelease();

protected:
    // CXImageDrawImpl
    void    ReleaseData();

    HRESULT DrawImpl(IN XCANVAS xCanvas, IN XIMAGE xImage, IN const RECT* lpSrc, IN const RECT* lpDes);

protected:
    // CXImageDrawImpl
    XString m_strXNC;

    XIMAGE  m_xImage;
    XIMAGE  m_xColorizeImage;
    DWORD   m_dwFlags;

    SIZE    m_Size;

    INT     m_nHorzIndex;
    INT     m_nVertIndex;

    INT     m_nHorzCount;
    INT     m_nVertCount;

    BYTE            m_byAlphaValue;
    COLORREF        m_clrTrans;
    eImageAlphaMode m_nAlphaMode;

    ImageDrawType   m_DrawType;
    ImageDrawParams m_DrawParams;

    struct stBufferInfo
    {
        XIMAGE  xBuffer;
        int     nRef;
        SIZE    size;
    };
    typedef std::map<HANDLE, stBufferInfo>    BufferMap;
    BufferMap   m_BufferMap;
};
